![]() |
![]() |
|
Ein SqlDataAdapter muss wissen, auf welcher Verbindung er einen Befehl absetzen soll. Zudem muss er selbstverständlich auch den abzusetzenden Befehl kennen. Die Konstruktoren bieten mehrere Kombinationsmöglichkeiten, dem DataAdapter die von ihm benötigten Informationen zu übergeben. Die Eigenschaft »SelectCommand«Verwenden Sie den parameterlosen Konstruktor, müssen Sie der Eigenschaft SelectCommand die Referenz auf ein SqlCommand-Objekt zuweisen.
Die Klasse SqlDataAdapter stellt weder eine Eigenschaft noch eine Methode bereit, mit der wir eine Verbindungszeichenfolge oder ein Connection-Objekt festlegen können. Das ist aber auch nicht weiter schlimm, da das Command-Objekt seinerseits selbst alle Verbindungsinformationen enthält.
26.4.2 Den lokalen Datenspeicher mit der Methode »Fill« füllen
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fill |
| Update |
Mit der Methode Fill wird der lokale Datenspeicher mit dem Ergebnis einer SELECT-Abfrage gefüllt. Dazu wird für die Dauer der Abfrageoperation eine Verbindung zur Datenquelle geöffnet und nach deren Beendigung wieder geschlossen. Die empfangenen Daten kann der Anwender ändern, er kann auch Datensätze löschen oder neue hinzufügen. Während dieser Zeit besteht kein Kontakt zur Datenbank.
Zu einem späteren Zeitpunkt sollen die Änderungen natürlich auch in die Originaldatenquelle zurückgeschrieben werden. Dazu muss die Methode Update des SqlDataAdapters aufgerufen werden. Der SqlDataAdapter sorgt dafür, dass die Verbindung mit den bekannten Verbindungsinformationen erneut aufgebaut und nach Beendigung der Aktualisierung automatisch geschlossen wird. Die Aktualisierung der Datenquelle ist ein komplexes Thema, auf das später in diesem Buch noch eingegangen wird. Sie sollten aber bereits jetzt wissen, dass dem SqlDataAdapter auch bei der Aktualisierung eine wichtige Rolle zukommt.
Die Methode Fill wollen wir einschließlich aller Konsequenzen etwas genauer unter die Lupe nehmen. Fill ist vielfach überladen, wobei ich Ihnen zwei Überladungen vorstellen möchte:
| Public Fill(DataTable) As Integer |
| Public Fill(DataSet) As Integer |
Dem Aufruf wird entweder ein DataTable- oder ein DataSet-Objekt übergeben. Beide sind unabhängig vom .NET-Datenprovider und gehören zum Namespace System.Data. Ein DataTable-Objekt entspricht einer Tabelle in der Datenbank. Es hat die Spalten, die in der SELECT-Abfrage angegeben worden sind, und enthält die Datensätze, die das Ergebnis der SELECT-Abfrage bilden. Ein DataSet-Objekt können Sie sich als einen Container für mehrere DataTable-Objekte vorstellen.
Im folgenden Beispiel wird die Tabelle in einem DataSet gefüllt mit drei Spalten der Tabelle authors. Dabei soll es jedoch nicht bleiben. Nach dem Füllen wollen wir uns auch noch vom Erfolg unserer Bemühungen überzeugen und die Datenzeilen im Konsolenfenster sehen. Das ist die Aufgabe der For Each-Schleife, auf die ich an dieser Stelle noch nicht eingehen werde.
| ' ------------------------------------------------------ |
| ' Beispiel: ...\Kapitel 26\DataSetFüllen |
| ' ------------------------------------------------------ |
| Imports System.Data.SqlClient |
| Module Module1 |
| Sub Main() |
| Dim con As SqlConnection = New SqlConnection() |
| con.ConnectionString = "..." |
| Dim cmd As New SqlCommand |
| cmd.Connection = con |
| cmd.CommandText = "SELECT au_id, au_lname, city FROM authors" |
| Dim ds As New DataSet |
| Dim da As SqlDataAdapter = New SqlDataAdapter(cmd) |
| da.Fill(ds) |
| For Each row As DataRow In ds.Tables(0).Rows |
| Console.WriteLine("{0,-13}{1,-25}{2}", _ |
| row("au_id"), row("au_lname"), row("city")) |
| Next |
| Console.ReadLine() |
| End Sub |
| End Module |
Nach dem Füllen einer DataTable oder eines DataSets gibt es keine Verbindung mehr zum DataAdapter. Das bedeutet, dass weder der DataAdapter eine Referenz auf das Objekt hat, das er gefüllt hat, noch weiß das gefüllte Objekt, von wem es gefüllt worden ist.
| Dim da As SqlDataAdapter = New SqlDataAdapter(cmd) |
wird das SqlDataAdapter-Ojekt erzeugt und dabei über das SqlCommand-Objekt cmd unter anderem die Referenz auf das Verbindungsobjekt con übergeben. Auffällig ist, dass niemals die Open-Methode aufgerufen wird, um die Abfrage zu übermitteln. Das ist aber auch nicht nötig, denn mit
| da.Fill(tbl) |
wird der DataAdapter die Verbindung selbstständig öffnen, die Ergebnisse abfragen und die Verbindung auch selbstständig schließen. Das steht ganz im Gegensatz zu den Execute-Methoden des Command-Objekts, die dieses intelligente Verhalten nicht zeigen und auf das ausdrückliche Öffnen der Verbindung angewiesen sind.
Sie dürfen allerdings auch explizit eine Verbindung vor dem Aufruf von Fill mit Open öffnen. Der DataAdapter wird das bemerken und die Verbindung nicht in Eigenregie schließen, wenn die Abfrageresultate eingetroffen sind. Es liegt dann in Ihrer Verantwortung, dafür zum frühestmöglichen Zeitpunkt zu sorgen.
| ... |
| con.Open() |
| da.Fill(tbl) |
| con.Close() |
Angenommen, es wird zweimal hintereinander die Fill-Methode aufgerufen, ohne vor dem zweiten Aufruf das DataSet oder die DataTable zu leeren, also:
| ... |
| da.Fill(ds) |
| ... |
| da.Fill(ds) |
Die Idee, die dem doppelten Aufruf zugrunde liegt, könnte die Aktualisierung des DataSets sein. Allerdings werden nun die Datensätze in der Tabelle doppelt erscheinen. Mit dem ersten Aufruf der Fill-Methode wird das DataTable-Objekt erzeugt, und die Datensätze werden hineingeschrieben, mit dem zweiten werden die Datensätze einfach noch einmal aus der Datenquelle bezogen und in die schon vorhandene Tabelle kopiert.
Der Grund dieses im ersten Moment etwas sonderbaren Verhaltens ist darin zu finden, dass die Primärschlüsselspalte der Originaltabelle nicht automatisch zur Primärschlüsselspalte der DataTable wird. Primärschlüssel dienen unter anderem zur Vermeidung von duplizierten Datensätzen und müssen in der Datenquelle festgelegt werden. Die DataTable übernimmt diese jedoch nicht.
| Hinweis |
|
Das DataTable-Objekt hat eine Eigenschaft PrimaryKey. Wird diese gesetzt, wird der Data-Adapter die doppelten Zeilen finden und die alten Werte verwerfen. Mehr Informationen darüber erhalten erhalten Sie später. |
Wird die Methode Fill hintereinander auf verschiedene DataAdapter aufgerufen, wird jeweils eine neue Verbindung benötigt. Daran ändert sich auch nichts, wenn allen Aufrufen dieselbe Verbindungszeichenfolge zugrunde liegt.
| ... |
| Dim daAuthors As SqlDataAdapter = _ |
| New SqlDataAdapter(strSQL1, con) |
| Dim daTitles As SqlDataAdapter = _ |
| New SqlDataAdapter(strSQL2, con) |
| Dim dsAuthors As New DataSet |
| Dim dsTitles As New DataSet |
| daAuthors.Fill(dsAuthors) |
| ... |
| daTitles.Fill(dsTitles) |
Der zweimalige Aufruf von Fill hat zur Folge, dass in diesem Codefragment unnötigerweise Leistungseinbußen in Kauf genommen werden müssen, weil in jedem Fall ein impliziter Open- bzw. Close-Aufruf auf die Verbindung erfolgt.
Wollen Sie sicherstellen, dass eine Verbindung von beiden DataAdapter-Objekten gleichermaßen benutzt wird, müssen Sie die Steuerung selbst übernehmen und mit der Open-Methode die Verbindung vor dem ersten Füllen des DataDets bzw. der DataTable öffnen.
| ... |
| con.Open() |
| daAuthors.Fill(dsAuthors) |
| ... |
| daTitles.Fill(dsTitles) |
| con.Close() |
Das DataSet verwaltet alle Tabellen, die in ihm enthalten sind, in einer Collection, deren Referenz die Eigenschaft Tables des DataSets liefert. Über
| dsTables(0) |
können Sie daher auf die erste Tabelle in der Tabellenauflistung zugreifen, beispielsweise um die Daten auszuwerten. Angegeben wird entweder der Index der Tabelle in der Auflistung oder deren Name. Standardmäßig ist der Name der ersten Tabelle Table, der der zweiten Table1 usw. Mit einer Überladung der Fill-Methode können Sie schon beim Füllen des DataSets einen besser beschreibenden Bezeichner festlegen, z. B.:
| da.Fill(ds, "Autoren") |
Sich für diese Überladung zu entscheiden, kann vorteilhaft sein, wenn Sie das DataSet mit mehreren Tabellen füllen wollen.
| cmd.CommandText = "SELECT au_id, au_lname, city FROM authors" |
| Dim da As SqlDataAdapter = New SqlDataAdapter(cmd) |
| Dim ds As New DataSet |
| con.Open() |
| da.Fill(ds, "Autoren") |
| cmd.CommandText = "SELECT * FROM titles" |
| da.Fill(ds, "Titel") |
| con.Close() |
Die Referenz auf die Tabelle, die alle Titel enthält, können Sie jetzt gleichwertig mit
| ds.Tables(1) |
oder
| ds.Tables("Titel") |
abrufen.
Liegt eine DataTable im Speicher, können die Daten nicht nur angezeigt, sondern auch verändert werden. Die Aktualisierungen werden mit der Update-Methode des DataAdapters an die Originaldatenbank geschickt und dort gespeichert. Viele Spalten einer Tabelle unterliegen aber Gültigkeitsregeln: Beispielsweise lassen einige nur eine maximale Zeichenanzahl zu, andere schreiben einen eindeutigen Eintrag innerhalb der Datensätze der Tabelle vor oder lassen keinen NULL-Wert zu.
Eine DataTable oder ein DataSet, das wir mit Fill füllen, ist sehr dumm. Es enthält zwar alle angeforderten Daten, weiß aber nichts von den Gültigkeitsregeln, die in der Datenbank festgelegt worden sind. Die Folge ist, dass in der Anwendung die Daten beliebig verändert werden können, ohne dass eine Überprüfung erfolgt. Der Versuch, die Änderungen in die Datenbank zu schreiben, wird jedoch scheitern, weil die Datenbank vor der endgültigen Aktualisierung zuerst die Änderungen mit den Gültigkeitsregeln vergleicht und die Verletzung feststellen wird. Es kommt zu einer Ausnahme in der Anwendung.
Im folgenden Beispiel wird der Datensatz eines bestimmten Autors anhand der Autoren-ID aus der authors-Tabelle abgefragt und – falls die Abfrage einen Datensatz liefert – angezeigt. Der Eintrag in der Spalte city, der Wohnort des Autors, kann nach Aufforderung neu festgelegt werden. Allerdings ist diese Spalte auf maximal 20 Zeichen in der Originaltabelle beschränkt.
Die Aktualisierungslogik mit Update soll hier noch nicht erklärt werden, ebenso wenig die Ausgabe der Abfrage an der Konsole.
| ' ------------------------------------------------------ |
| ' Beispiel: ...\Kapitel 26\DataSetOhneSchema |
| ' ------------------------------------------------------ |
| Imports System.Data.SqlClient |
| Module Module1 |
| Sub Main() |
| Dim con As New SqlConnection |
| con.ConnectionString = "..." |
| Dim cmd As New SqlCommand |
| cmd.Connection = con |
| cmd.CommandText = "SELECT * FROM authors " & _ |
| "WHERE au_id='172–32–1176'" |
| Dim da As SqlDataAdapter = New SqlDataAdapter(cmd) |
| Dim ds As New DataSet |
| da.Fill(ds) |
| Dim tbl As DataTable = ds.Tables(0) |
| ' Anzeige der Daten |
| If tbl.Rows.Count > 0 Then |
| Dim row As DataRow = tbl.Rows(0) |
| ' Anzeige aller Spalten des Abfrageergebnisses |
| For Each column As DataColumn In tbl.Columns |
| Console.WriteLine(row(column)) |
| Next |
| End If |
| Console.WriteLine() |
| Console.Write("Neuer Wohnort: ") |
| ' tbl.Columns("city").MaxLength = 20 |
| tbl.Rows(0)("city") = Console.ReadLine() |
| ' Datenbank aktualisieren |
| Dim cb As SqlCommandBuilder = New SqlCommandBuilder(da) |
| da.Update(tbl) |
| End Sub |
| End Module |
Beachten Sie, dass die Ausnahme erst nach dem Aufruf der Update-Methode auftreten wird, ein Zeichen dafür, dass die Datenbank die Aktualisierung abgelehnt hat. Der Ansatz, der Datenbank die Verantwortung zu überlassen, ist keine gute Lösung. Sicher werden wir deren Überprüfung nicht abstellen können, aber wir können den Netzverkehr entlasten, der unweigerlich auftritt, wenn die Datenbank eine Aktualisierung ablehnt. Das wird sich besonders bei stark frequentierten Datenbanken positiv auswirken.
Besser ist es, bereits die Eingabe des Anwenders zu überprüfen und ihm gegebenenfalls mitzuteilen, wenn er gegen die in der Datenbank festgelegten Gültigkeitsregeln verstößt. Dazu werden jedoch die Schemainformationen benötigt. Im Beispiel sind diese noch auskommentiert.
| tbl.Columns("city").MaxLength = 20 |
Sie können diese Auskommentierung aufheben und werden feststellen, dass jetzt die Ausnahme nicht mehr in der Zeile mit der Update-Methode auftritt, sondern in der Eingabeanweisung:
tbl.Rows(0)("city") = Console.ReadLine()
Die Datenbank wird, da die Spalte city in der Tabelle des DataSets mit der Eigenschaft MaxLength auf eine Maximallänge von 20 Zeichen eingeschränkt wird, in jedem Fall gültige Daten erhalten.
Es gibt drei Möglichkeiten, einem Dataset bzw. einer DataTable Schemainformationen bereitzustellen:
| Die Schemainformationen werden von der Datenbank mit der Methode FillSchema des DataAdapters bezogen. |
| Die Gültigkeitsregeln werden mittels Programmcode für alle betreffenden Tabellen und Spalten festgelegt. |
| Die Methode ReadXmlSchema des DataSet-Objekts, um Schemainformationen in eine XSD-Datei (XML Schema Definition) zu speichern. |
| Um die in der Anwendung eingegebenen Daten mittels Programmcode zu überprüfen, hat das DataColumn-Objekt, mit dem eine Spalte der Tabelle beschrieben wird, einige Eigenschaften: |
| ReadOnly |
| AllowDBNull |
| MaxLength |
| AutoIncrement |
| Unique. |
Auch ein DataTable-Objekt unterstützt das anwendungsseitige Definieren von Einschränkungen. Unter anderem kann der Eigenschaft PrimaryKey die Primärschlüsselspalte bzw. können die Primärschlüsselspalten einer Tabelle übergeben werden. Wir werden uns, wenn wir DataTable und DataColumn erörtern, mit den genannten Eigenschaften noch eingehend beschäftigen.
Die einfachste Variante, Schemainformationen bereitzustellen, ist die Methode FillSchema, mit der Sie Schemainformationen für ein DataSet oder eine DataTable direkt bei der Datenbank abrufen können. Basis ist dabei das in SelectCommand beschriebene SELECT-Kommando.
FillSchema ist mehrfach überladen. Zwei Überladungen seien an dieser Stelle gezeigt.
| Public Function FillSchema(DataTable, SchemaType) As DataTable |
| Public Overrides Function FillSchema(DataSet, SchemaType) As DataTable() |
Allen Überladungen ist gemein, dass sie ein Argument vom Typ der Enumeration SchemaType erwarten. Diese Aufzählung hat zwei Mitglieder: Source und Mapped. Über diesen Parameter wird gesteuert, ob der DataAdapter die Zuordnungen, die in der DataTableMappingCollection und der DataColumnMappingCollection angegeben sind, verwenden soll.
| Member | Beschreibung |
| Mapped | Der DataAdapter verwendet die Zuordnungen der Spalten in der TableMappings-Auflistung. |
| Source | Der DataAdapter ignoriert die Zuordnungen der Spalten in der TableMappings-Auflistung. |
Der Aufruf der Methode mit beispielsweise
| da.FillSchema(ds, SchemaType.Source) |
ist einerseits natürlich sehr bequem, aber andererseits dürfen Sie nicht vergessen, dass dabei sowohl das Netzwerk als auch die Datenbank belastet werden. Die in Tabelle 26.3 erwähnten TableMappings werden weiter unten noch angesprochen.
Auf der Buch-CD finden Sie das Beispiel FillSchemaDemo, das auf dem Code des Beispiels DataSetOhneSchema basiert, aber zusätzlich das Schema der Tabelle von der Originaldatenbank bezieht.
Mit den Methoden WriteXmlSchema und ReadXmlSchema des Datasets können Sie die Schemainformationen in eine XML-Schemadatei schreiben und später auswerten. XML-Schemadateien haben üblicherweise die Dateiendung .XSD.
Bevor Sie das Schema eines DataSets in einer Schemadatei speichern, muss das Schema bekannt sein. Sie können sich daher zur Entwicklungszeit das Schema einmalig mit FillSchema besorgen und dann mit WriteXmlSchema in einer Datei speichern.
| ds.WriteXmlSchema("C:\MyDataSetSchema.xsd") |
Damit die XSD-Datei auch Nutzen bringt, muss sie zusammen mit der Applikation ausgeliefert werden.
Zur Laufzeit erzeugen Sie zuerst das DataSet-Objekt, lesen anschließend die Schemadatei ein und füllen das DataSet mit den Daten.
| ... |
| Dim ds As New DataSet |
| ds.ReadXmlSchema("C:\MyDataSetSchema.xsd") |
| da.Fill(ds) |
In Abbildung 26.3 sehen Sie die Schemadatei, die auf einer Abfrage basiert, die alle Spalten eines bestimmten Autors aus der Tabelle authors wiedergibt.

Hier klicken, um das Bild zu Vergrößern
Abbildung 26.3 Schemadatei (.XSD-Datei)
Verhältnismäßig aufwändig ist die programmatische Bereitstellung eines Schemas. Mit den Eigenschaften AllowDBNull, MaxLength, Unique einer DataColumn sowie PrimaryKey einer DataTable können Sie Datenüberprüfungsmechanismen implementieren. Mit ReadOnly=True haben Sie zudem die Möglichkeit, gültige Daten vor einer Veränderung durch den Benutzer zu schützen.
Typischer Programmcode könnte beispielsweise wie folgt aussehen:
| ds.Tables(0).Columns("au_id").MaxLength = 11 |
| ds.Tables(0).Columns("au_lname").MaxLength = 40 |
| ds.Tables(0).Columns("au_fname").MaxLength = 20 |
| ds.Tables(0).Columns("contract").AllowDBNull = False |
| ds.Tables(0).PrimaryKey = _ |
| New DataColumn() {ds.Tables(0).Columns("au_id")} |
Sind in einem DataSet mehrere Tabellen enthalten, die miteinander in Beziehung stehen, muss gegebenenfalls auch die Beziehung codiert werden. Die Klasse DataRelation, welche die Beziehung zwischen zwei Tabellen beschreibt, werden wir uns später noch ansehen.
Ein DataTable-Objekt veröffentlicht über die Eigenschaft Constraints die Referenz auf eine Auflistung vom Typ ConstraintCollection.
| Public ReadOnly Property Constraints As ConstraintCollection |
In der Auflistung werden Constraint-Objekte verwaltet, mit denen Einschränkungen der DataTable definiert werden.
Constraint ist eine abstrakte Basisklasse, von der es zwei Ableitungen gibt:
| UniqueConstraint |
| ForeignKeyConstraint |
Eine Einschränkung beschreibt eine Regel, mit der die Datenintegrität gewährleistet wird. Löschen Sie beispielsweise einen Datensatz in einer Tabelle, die mit anderen Tabellen verknüpft ist, muss sichergestellt werden, dass in den verknüpften Tabellen der entsprechende Datensatz ebenfalls gelöscht wird, der Wert der betroffenen Spalte auf NULL gesetzt oder ein Standardwert festgelegt wird. Zudem kann eine Einschränkung auch so wirken, dass die Aktion überhaupt nicht ausgeführt wird. Die beschriebenen Einschränkungen in diesem Fall werden durch ein ForeignKeyConstraint-Objekt gesteuert.
ForeignKeyConstraint-Objekte explizit zu erzeugen ist in den meisten Fällen nicht nötig. Beim Erzeugen einer DataRelation zwischen zwei DataTable-Objekten innerhalb eines DataSets wird ein ForeignKeyConstraint-Objekt automatisch erstellt.
Mit der Eigenschaft Unique einer DataColumn können Sie angeben, ob die Werte in einer Spalte eindeutig sind. Dazu legen Sie
fest. Gleichzeitig wird der ConstraintCollection der DataTable ein Objekt vom Typ der Klasse UniqueConstraint hinzugefügt. Normalerweise brauchen Sie also dieses Objekt nicht per Programmcode zu erzeugen. Nur wenn Sie sicherstellen müssen, dass die Kombination aus mehreren Spalten eindeutig ist, wird Ihnen keine andere Möglichkeit bleiben.
Auch die Festlegung einer Primärschlüsselspalte mit der Eigenschaft PrimaryKey der DataTable oder die Kombination mehrerer Spalten zu einem Primärschlüssel wird die implizite Erstellung eines UniqueConstraint-Objekts zur Folge haben.
Jetzt wollen wir uns die Unterstützung des Visual Studios 2005 ansehen, um einen SqlData-Adapter zu erstellen, der ebenfalls als Steuerelement nach vorhergehendem Hinzufügen in der Lasche Daten der Toolbox angeboten wird. Ziehen Sie das Control in den Forms Designer, öffnet sich ein Dialog, der Sie durch die Konfiguration des DataAdapters führt.
Im ersten Schritt muss die Verbindung angegeben werden, auf welcher der SqlDataAdapter seine Aufgaben ausführen soll. Haben Sie bereits ein SqlConnection-Control in das Projekt gezogen, können Sie auch diese Verbindung auswählen. Sie können aber auch eine neue Verbindung definieren, indem Sie auf die entsprechend beschriftete Schaltfläche klicken.

Hier klicken, um das Bild zu Vergrößern
Abbildung 26.4 Konfiguration der Verbindung des SqlDataAdapters
Im zweiten Schritt geben Sie den Abfragetyp an. Dazu können Sie eine SQL-Anweisung festlegen, eine gespeicherte Prozedur erstellen oder auf eine existierende gespeicherte Prozedur zurückgreifen (Abbildung 26.5).

Hier klicken, um das Bild zu Vergrößern
Abbildung 26.5 Auswahl des Befehlstyps
Fällt Ihre Entscheidung auf SQL-Anweisungen verwenden, öffnet sich ein Fenster, in dem Sie entweder direkt das SQL-Kommando eingeben oder den Abfrage-Generator starten können, der bereits in Abbildung 26.2 gezeigt wurde.

Hier klicken, um das Bild zu Vergrößern
Abbildung 26.6 Dialogfenster zum Erzeugen von SQL-Anweisungen
Die Schaltfläche Erweiterte Optionen... öffnet ein Dialogfenster, dessen Auswahloptionen im Zusammenhang mit der Aktualisierung der Datenbank stehen (siehe Abbildung 26.7). Am Ende dieses Kapitels werden wir das Aktualisieren von Daten erörtern. Daher gehe ich an dieser Stelle nicht näher auf die Einstellmöglichkeiten und deren Konsequenzen ein.

Hier klicken, um das Bild zu Vergrößern
Abbildung 26.7 Optionseinstellungen, die im Zusammenhang mit der Aktualisierung stehen
Aus allen Angaben, die Sie gemacht haben, generiert der Assistent die Verbindungsinformationen und erstellt die Auswahl- und Aktualisierungsanweisungen für das betreffende Kommando.
| << zurück |
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken.
Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die
gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich
geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung,
Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.